//
//  TouchDrawView.m
//  TouchTracker
//
//  Created by Rafal Rebacz on 5/14/13.
//  Copyright (c) 2013 Rafal Rebacz. All rights reserved.
//

#import "TouchDrawView.h"
#import "Line.h"
#import "Circle.h"

@implementation TouchDrawView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self)
    {
        // Initialization code
        linesInProcess = [[NSMutableDictionary alloc] init];
        circlesInProcess = [[NSMutableDictionary alloc] init];
        completeLines = [[NSMutableArray alloc] init];
        completeCircles = [[NSMutableArray alloc] init];

        [self setBackgroundColor:[UIColor whiteColor]];
        [self setMultipleTouchEnabled:YES];
    }
    return self;
}

-(void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 10);
    CGContextSetLineCap(context, kCGLineCapRound);
    
    [[UIColor blackColor] set];
    for (Line *line in completeLines)
    {
        CGContextMoveToPoint(context, line.begin.x, line.begin.y);
        CGContextAddLineToPoint(context, line.end.x, line.end.y);
        CGContextStrokePath(context);
    }
    
    [[UIColor redColor] set];
    for (NSValue *value in completeCircles)
    {
        Line *line = [linesInProcess objectForKey:value];

//  SILVER CHALLENGE
//        CGFloat a = line.end.x - line.begin.x;
//        CGFloat b = line.end.y - line.begin.y;
//        CGFloat rads = atan2f(b, a);
//        CGFloat bearingDegrees = ((rads * (180.0 / M_PI)) / 180) * 255.0;
//        bearingDegrees = bearingDegrees > 0 ? bearingDegrees : - bearingDegrees;
//        NSLog(@"bearingDegrees: %.2f", bearingDegrees);
//        [[UIColor colorWithRed:bearingDegrees/255.0 green:bearingDegrees/255.0 blue:bearingDegrees/255.0 alpha:1] set];
        
        CGContextMoveToPoint(context, line.begin.x, line.begin.y);
        CGContextAddLineToPoint(context, line.end.x, line.end.y);
        CGContextStrokePath(context);
    }
    
    for(NSValue *value in circlesInProcess)
    {
        Circle *c = [circlesInProcess objectForKey:value];
        
        CGContextAddArc(context, c.center.x, c.center.y, c.radius, 0, 2 * M_PI, 1);
        CGContextDrawPath(context, kCGPathStroke);
    }
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    
//    for(UITouch *touch in touches)
//    {
        if([[touches anyObject] tapCount] > 1)
        {
            [self clearLines];
            
            return;
        }

        if([touches count] == 1)
        {
            UITouch *touch = [touches anyObject];
            NSValue *key = [NSValue valueWithNonretainedObject:touch];
            
            CGPoint loc = [touch locationInView:self];
            Line *newLine = [[Line alloc] init];
            [newLine setBegin:loc];
            [newLine setEnd:loc];
            
            [linesInProcess setObject:newLine forKey:key];
        }
        else if([touches count] == 2)
        {
            UITouch *firstTouch = [[touches allObjects] objectAtIndex:0];
            UITouch *secondTouch = [[touches allObjects] objectAtIndex:1];
            CGPoint firstTouchLoc = [firstTouch locationInView:self];
            CGPoint secondTouchLoc = [secondTouch locationInView:self];
            
            Circle *c = [[Circle alloc] init];
            c.radius = sqrt(pow(secondTouchLoc.x - firstTouchLoc.x, 2) + pow(secondTouchLoc.y - firstTouchLoc.y, 2)) / 2.0;
            c.center = CGPointMake(MIN(firstTouchLoc.x, secondTouchLoc.x) + (firstTouchLoc.x - secondTouchLoc.x) / 2,
                                   MIN(firstTouchLoc.y, secondTouchLoc.y) + c.radius / 2);
            
            NSValue *key = [NSNumber numberWithInt:c.circleId];
            
            [circlesInProcess setObject:c forKey:key];
            
            NSLog(@"%d", c.circleId);
        }
//    }
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
        UITouch *touch = [touches anyObject];
        NSValue *key = [NSValue valueWithNonretainedObject:touch];
        
        Line *line = [linesInProcess objectForKey:key];
        CGPoint loc = [touch locationInView:self];
        [line setEnd:loc];

        if([touches count] == 2)
    {
        UITouch *firstTouch = [[touches allObjects] objectAtIndex:0];
        UITouch *secondTouch = [[touches allObjects] objectAtIndex:1];
        CGPoint firstTouchLoc = [firstTouch locationInView:self];
        CGPoint secondTouchLoc = [secondTouch locationInView:self];

        CGFloat radius = sqrt(pow(secondTouchLoc.x - firstTouchLoc.x, 2) + pow(secondTouchLoc.y - firstTouchLoc.y, 2)) / 2.0;
        CGPoint center = CGPointMake(MIN(firstTouchLoc.x, secondTouchLoc.x) + (firstTouchLoc.x - secondTouchLoc.x) / 2,
                                     MIN(firstTouchLoc.y, secondTouchLoc.y) + radius / 2);
        Circle *c = [circlesInProcess objectForKey:[NSNumber numberWithInt:Circle.currentCircleId]];
        c.radius = radius;
    }
    
    [self setNeedsDisplay];
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self endTouches:touches];
}

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self endTouches:touches];    
}

-(void)endTouches:(NSSet *)touches
{
    if([touches count] == 1)
    {
        NSValue *key = [NSValue valueWithNonretainedObject:[touches anyObject]];
        
        Line *line = [linesInProcess objectForKey:key];
        
        if(line)
        {
            [completeLines addObject:line];
            [linesInProcess removeObjectForKey:key];
        }
    }
    else if([touches count] == 2)
    {
        NSValue *key = [NSNumber numberWithInt:Circle.currentCircleId];
        
        Circle *c = [circlesInProcess objectForKey:key];
        
        if(c)
        {
            [completeCircles addObject:c];
            [circlesInProcess removeObjectForKey:key];
        }
    }
    
    [self setNeedsDisplay];
}

- (void)clearLines
{
    [linesInProcess removeAllObjects];
    [completeLines removeAllObjects];
    [circlesInProcess removeAllObjects];
    [completeCircles removeAllObjects];
    
    [self setNeedsDisplay];
}

@end
